import React from 'react'
import { connect } from 'react-redux'
import { Icon, Input, List, Divider } from 'antd'
import {messages, deepCopy} from "share/common";
import menuRoute from "routes/menuRoute";
import commonQuestionService from "containers/help-center-user/common-question/common-question.service";
import errorMessage from "share/errorMessage";
import docService from "containers/help-center-user/doc/doc.service";
import routeService from 'routes/route.service';
import mainService from 'containers/main.service';
import 'styles/main/components/global-search.scss'

const SEARCH_STANDARD = { //全局搜索的数组名规范，是搜索结果列表的初始值
  personalMenu: [],
  adminMenu: [],
  helpDoc: [],
  FAQ: []
};
const SEARCH_TITLE = {
  personalMenu: messages('dashboard.key118')/*个人模式*/,
  adminMenu: messages('dashboard.key101')/*管理员模式*/,
  helpDoc: messages('dashboard.key119')/*帮助文档*/,
  FAQ: messages('dashboard.key120')/*常见问题*/
};

class GlobalSearch extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      menu: menuRoute.menu,
      hasGetSearchList: false,
      searchLoad: false,
      searchList: JSON.parse(JSON.stringify(SEARCH_STANDARD)),//存储处理完的搜索数据库
      searchResult: JSON.parse(JSON.stringify(SEARCH_STANDARD)),//存储搜索结果列表
      keyWords: "", //搜索框里当前搜索字段
      isFocus: false, //搜索框是否聚焦
      selectedSearchItem: -1
    }
  }

  componentWillMount() {
    this.setState({
      isOldCompany: this.props.isOldCompany,
      languageCode: this.props.languageCode,
      tenantMode: this.props.tenantMode,
      adminMode: this.props.adminMode
    })
  }

  componentWillUnmount() {
    if (window.addEventListener) {
      window.removeEventListener('keydown', this.handleKeyPress);
    } else {
      window.detachEvent('onkeydown', this.handleKeyPress);
    }
  }

  componentDidMount() {
    if (window.addEventListener) {
      window.addEventListener('keydown', this.handleKeyPress);
    } else {
      window.attachEvent('onkeydown', this.handleKeyPress);
    }
  }

  componentWillReceiveProps(nextProps) {
    this.setState({
      isOldCompany: nextProps.isOldCompany,
      languageCode: nextProps.languageCode,
      tenantMode: nextProps.tenantMode,
      adminMode: nextProps.adminMode
    })
  }

  handleKeyPress = (e) => {
    //todo:目前win下win+shift+f也起效 还是要对不同系统做判断
    let keyCode = e.keyCode || e.which || e.charCode;
    let shiftKey = e.shiftKey;
    let ctrlKey = e.ctrlKey || e.metaKey;//metaKey win下为win键 Mac下为command键
    if (ctrlKey && shiftKey && keyCode === 70) {
      this.handleFocus();
    }
  };

  handleKeyDown = (e) => {
    let keyCode = e.keyCode || e.which || e.charCode;
    const {searchResult, selectedSearchItem} = this.state;
    let searchTypes = Object.keys(SEARCH_STANDARD);
    let totalLength = 0;
    let selectedTemp = -1;
    searchTypes.map((typeItem) => {
      totalLength += searchResult[typeItem].length
    });
    if (keyCode === 40) {
      let listTemp = 0;
      let totalTemp = 0;
      selectedTemp = (selectedSearchItem === totalLength - 1) ? 0 : selectedSearchItem + 1;
      //判断被选项在哪个列表里
      searchTypes.map((typeItem) => {
        totalTemp += searchResult[typeItem].length;
        if (selectedTemp > totalTemp - 1) {
          searchResult[typeItem].length && listTemp++
        }
      });
      //选择时使列表跟着滑动
      if (document.getElementsByClassName("search-result-list")[0]) {
        document.getElementsByClassName("result-list-item")[listTemp].scrollTop = document.getElementsByClassName("ant-list-item")[selectedTemp].offsetTop;
      }
      this.setState({
        selectedSearchItem: selectedTemp
      })
    }
    if (keyCode === 38) {
      let listTemp = 0;
      let totalTemp = 0;
      selectedTemp = (selectedSearchItem === 0 || selectedSearchItem === -1) ? totalLength - 1 : selectedSearchItem - 1;
      //判断被选项在哪个列表里
      searchTypes.map((typeItem) => {
        totalTemp += searchResult[typeItem].length;
        if (selectedTemp > totalTemp -1) {
          searchResult[typeItem].length && listTemp++
        }
      });
      //选择时使列表跟着滑动
      if (document.getElementsByClassName("search-result-list")[0]) {
        document.getElementsByClassName("result-list-item")[listTemp].scrollTop = document.getElementsByClassName("ant-list-item")[selectedTemp].offsetTop;
      }
      this.setState({
        selectedSearchItem: selectedTemp
      })
    }
    if (keyCode === 13) {
      document.getElementsByClassName("selected")[0] && document.getElementsByClassName("selected")[0].click();
      this.setState({
        selectedSearchItem: -1
      })
    }
    if (keyCode === 27) {
      this.refs.searchButton.blur();
      this.setState({
        isFocus: false
      })
    }
  };

  menuRouterDeal = (item) => {
    routeService.menuRouterDeal(item, this.context, this.props.authToken);
  };

  /**
   * 处理菜单搜索数据：
   * 集团模式和公司模式的搜索做分开处理，该两种模式下管理员模式和非管理员模式下的可见菜单数据合并
   */
  getAllPermissionMenu = () => {
    const { isOldCompany } = this.state;
    const { user, newPermissionSortedMenus } = this.props;
    let menu = this.state.menu;
    //新权限下的搜索
    if(user.enableNewPermission) {
      menu = newPermissionSortedMenus;
    }
    let personalTenant = [];
    let personalCompany = [];
    let adminTenant = [];
    let adminCompany = [];
    let hasTenant = this.checkAuthorities('ROLE_TENANT_ADMIN');
    let hasAdmin = this.hasAnyAuthorities(['ROLE_TENANT_ADMIN', 'ROLE_COMPANY_ADMIN']);
    let adminCompanyObejct = { isShow: hasAdmin, itemList: adminCompany, mode: "" };
    let adminTenantObejct = { isShow: hasAdmin && hasTenant, itemList: adminTenant, mode: messages('dashboard.key87')/*集团模式*/};
    let personalCompanyObejct = { isShow: true, itemList: personalCompany, mode: "" };
    let personalTenantObejct = { isShow: hasTenant, itemList: personalTenant, mode: messages('dashboard.key87')/*集团模式*/ };

    let subMenu;
    let pushMenu = function (menuItem, name) {
      //fixbug 34369
      if(!user.enableNewPermission && menuItem.newPermission) {
        //如果是老权限 菜单仅仅给新权限的
        return;
      }
      if(menuItem.subMenu){
        subMenu = messages(`menu.${menuItem.key}`) + "/ ";
        menuItem.subMenu.map(subItem => pushMenu(subItem, subMenu + messages(`menu.${subItem.key}`)));
      }else if(mainService.checkMenuAuth(menuItem, menuItem.admin, menuItem.tenant, isOldCompany)) {
        if(!!user.enableNewPermission) {
          let admin = menuItem.admin;
          let company = menuItem.company;
          let tenant = menuItem.tenant;
          let employee = menuItem.employee;
          pushItem(menuItem, adminCompanyObejct, admin && company, name);
          pushItem(menuItem, adminTenantObejct, admin && tenant, name);
          pushItem(menuItem, personalCompanyObejct, employee && company, name);
          pushItem(menuItem, personalTenantObejct, employee && tenant, name);
        } else {
          // menuRoute规定 如果company与tenant都不设置，则都显示
          let parentAdmin = menuItem.parent && (menuRoute.getRouteItem(menuItem.parent).admin);
          let parentTenant = menuItem.parent && (menuRoute.getRouteItem(menuItem.parent).tenant);
          let parentCompany = menuItem.parent && (menuRoute.getRouteItem(menuItem.parent).company);
          let admin = menuItem.admin || parentAdmin;
          let company = menuItem.company || parentCompany;
          let tenant = menuItem.tenant || parentTenant;
          pushItem(menuItem, adminCompanyObejct, admin && (company || !tenant), name);
          pushItem(menuItem, adminTenantObejct, admin && (tenant || !company), name);
          pushItem(menuItem, personalCompanyObejct, !admin && (company || !tenant), name);
          pushItem(menuItem, personalTenantObejct, !admin && (tenant || !company), name);
        }
      }
    };

    let pushItem = function (menuItem, object, isShow, itemName) {
      if(object.isShow && isShow){
        object.itemList.push({
            key: menuItem.key,
            thirdTypeUrl: menuItem.thirdTypeUrl,
            url: menuItem.url,
            name: itemName,
            mode: object.mode
        });
      }
    };

    //把checkMenuAuth的判断集团模式员工模式的部分逻辑抽出来，可以不用写四遍判断了
    menu.forEach((menuItem) => {
      subMenu = "";
      pushMenu(menuItem, messages(`menu.${menuItem.key}`));
    });
    this.setState({
      searchList: Object.assign(this.state.searchList, {
        personalMenu: personalCompany.concat(personalTenant),
        adminMenu: adminCompany.concat(adminTenant)
      })
    });
  };

  getALLDocList = () => {
    return docService.getMenuList().then(res => {
      if (res.data && res.data.length) {
        let menuDataList = [];
        let docTitle = [];
        let docId = [];
        let getMenuDataList = arr => {
          arr.map((item, index) => {
            if (item.parentId === "0") {
              docTitle = [];
              docId = [];
            }
            docTitle.push(item.docTitle);
            docId.push(item.id);
            menuDataList.push({
              key: item.id,
              name: docTitle.join("/"),
              id: docId.join(",")
            });
            item.children && getMenuDataList(item.children);
            if (index === arr.length - 1 && !item.children) {
              docTitle.pop();
              docTitle.pop();
              docId.pop();
              docId.pop();
            }
            if (index !== arr.length - 1 && !item.children) {
              docTitle.pop();
              docId.pop();
            }
          })
        };
        getMenuDataList(res.data);
        this.setState({
          searchList: Object.assign(this.state.searchList, {
            helpDoc: menuDataList
          })
        });

      }
    })
  };

  getALLQuestionList = () => {
    commonQuestionService.getCategoryList('COMMONPROBLEM', this.state.languageCode).then(res => {
      let questionList = [];
      res.data && res.data.map(item => {
        item.commonProblems && item.commonProblems.map(ques => {
          let span= document.createElement('span');
          span.innerHTML= ques.answer || "";
          let answer = span.textContent || span.innerText;
          questionList.push({
            id: item.id,
            anchor: ques.id,
            name: `${item.name}/${ques.question}/${answer}`,
            title: item.name,
            question: ques.question,
            answer: answer
          })
        })
      });
      this.setState({
        searchList: Object.assign(this.state.searchList, {
          FAQ: questionList
        })
      });
    }).catch(err => {
      errorMessage(err.response,messages("common.operate.filed"));
    })
  };

  handleFocus = () => {
    const { hasGetSearchList } = this.state;
    const { newPermissionSortedMenus, user } = this.props;
    let showDocs = true;
    if(!!user.enableNewPermission){
      showDocs = newPermissionSortedMenus.filter(item => item.key === 'help-center-user').length;
    }
    if (!hasGetSearchList) { //获取并处理需要搜索的数据，且只处理一次
      this.setState({searchLoad: true});
      Promise.resolve()
        .then(() => this.getAllPermissionMenu())
        .then(() => showDocs && this.getALLDocList())
        .then(() => showDocs && this.getALLQuestionList()) //新权限可能没有帮助反馈菜单
        .then(() => this.setState({searchLoad: false, hasGetSearchList: true}));
    }
    if (window.addEventListener) {
      window.removeEventListener('keydown', this.handleKeyPress);
    } else {
      window.detachEvent('onkeydown', this.handleKeyPress);
    }
    this.refs.searchButton.focus();
    this.setState({
      isFocus: true
    });
  };

  clearSearchResult = () => {
    this.setState({
      keyWords: "",
      searchResult: Object.assign({}, SEARCH_STANDARD)
    })
  };

  handleClickSearchList = (type, item, e) => {
    const { tenantMode, adminMode } = this.state;
    const { handleModeChange, user, newPermissionSortedMenus } = this.props;
    let targetAdminMode = null;
    let targetTenantMode = null;
    switch (type) {
      case "personalMenu": {
        (tenantMode && !item.mode) && (targetTenantMode = false);
        (!tenantMode && item.mode) && (targetTenantMode = true);
        (adminMode === true) && (targetAdminMode = false);
        handleModeChange(targetAdminMode, targetTenantMode, item);
        this.clearSearchResult();
        this.setState({selectedSearchItem: -1});
        break;
      }
      case "adminMenu": {
        (tenantMode && !item.mode) && (targetTenantMode = false);
        (!tenantMode && item.mode) && (targetTenantMode = true);
        (adminMode === false) && (targetAdminMode = true);
        handleModeChange(targetAdminMode, targetTenantMode, item);
        this.clearSearchResult();
        this.setState({selectedSearchItem: -1});
        break;
      }
      case "helpDoc": {
        //新权限下帮助与反馈不一定是固定模式下的 可配置
        if(!!user.enableNewPermission) {
          targetAdminMode = !!newPermissionSortedMenus.filter(menuItem => menuItem.key === 'help-center-user')[0].admin;
          targetTenantMode = !!newPermissionSortedMenus.filter(menuItem => menuItem.key === 'help-center-user')[0].tenant;
        } else {
          (adminMode === true) && (targetAdminMode = false);
        }
        let tagertMenu = menuRoute.getRouteItem('doc', 'key');
        handleModeChange(targetAdminMode, targetTenantMode, tagertMenu.url.replace(":linkId", item.key));
        break;
      }
      case "FAQ": {
        if(!!user.enableNewPermission) {
          targetAdminMode = !!newPermissionSortedMenus.filter(menuItem => menuItem.key === 'help-center-user')[0].admin;
          targetTenantMode = !!newPermissionSortedMenus.filter(menuItem => menuItem.key === 'help-center-user')[0].tenant;
        } else {
          (adminMode === true) && (targetAdminMode = false);
        }
        let tagertMenu = menuRoute.getRouteItem('common-question', 'key');
        handleModeChange(targetAdminMode, targetTenantMode, tagertMenu.url.replace(":id", item.id));
        break;
      }
    }
  };

  handleSearchHuilianyi = (e) => {
    const {searchList} = this.state;
    let keyWords = e.target.value;
    if (!!e.target.value) {
      let searchTypes = Object.keys(SEARCH_STANDARD);
      let searchResultTemp = JSON.parse(JSON.stringify(SEARCH_STANDARD));
      searchTypes.map((typeItem) => {
        if(typeItem === "personalMenu" || typeItem === "adminMenu"){
          searchList[typeItem].map((item) => {
            if (item.name.toLocaleLowerCase().indexOf(e.target.value.toLocaleLowerCase()) > -1) {
              let indexStr = item.name.toLocaleLowerCase().indexOf(keyWords.toLocaleLowerCase());
              item.bStr = item.name.substr(0, indexStr);
              item.aStr = item.name.substr(indexStr + keyWords.length);
              searchResultTemp[typeItem].push(item);
            }
          })
        }
        if(typeItem === "helpDoc"){
          searchList[typeItem].map((item) => {
            if (item.name.toLocaleLowerCase().indexOf(e.target.value.toLocaleLowerCase()) > -1) {
              let title = item.name.split("/")[0];
              let content = item.name.substr(item.name.indexOf("/")+1);
              item.title = title;
              item.content = content;
              let titleIndex = title.toLocaleLowerCase().indexOf(keyWords.toLocaleLowerCase());
              let contentIndex = content.toLocaleLowerCase().indexOf(keyWords.toLocaleLowerCase());
              if(titleIndex > -1){
                item.titleBStr = title.substr(0, titleIndex);
                item.titleAStr = title.substr(titleIndex + keyWords.length);
              }
              if(contentIndex > -1){
                item.contentBStr = content.substr(0, contentIndex);
                item.contentAStr = content.substr(contentIndex + keyWords.length);
              }
              searchResultTemp[typeItem].push(item);
            }
          })
        }
        if(typeItem === "FAQ"){
          searchList[typeItem].map((item) => {
            if (item.name.toLocaleLowerCase().indexOf(e.target.value.toLocaleLowerCase()) > -1) {
              let titleIndex = item.title.toLocaleLowerCase().indexOf(keyWords.toLocaleLowerCase());
              let quesIndex = item.question.toLocaleLowerCase().indexOf(keyWords.toLocaleLowerCase());
              let ansIndex = item.answer.toLocaleLowerCase().indexOf(keyWords.toLocaleLowerCase());
              if(titleIndex > -1){
                item.titleBStr = item.title.substr(0, titleIndex);
                item.titleAStr = item.title.substr(titleIndex + keyWords.length);
              }
              if(quesIndex > -1){
                item.quesBStr = item.question.substr(0, quesIndex);
                item.quesAStr = item.question.substr(quesIndex + keyWords.length);
              }
              if(ansIndex > -1){
                item.ansBStr = item.answer.substr(0, ansIndex);
                item.ansAStr = item.answer.substr(ansIndex + keyWords.length);
              }
              searchResultTemp[typeItem].push(item);
            }
          })
        }
      });
      this.setState({
        searchResult: searchResultTemp,
        keyWords: e.target.value
      })
    } else {
      this.setState({
        keyWords: ""
      })
    }
  };

  renderSearchList() {
    const {searchResult, keyWords, isFocus, selectedSearchItem, searchLoad} = this.state;
    let searchTypes = Object.keys(SEARCH_STANDARD);
    let showListFlag = false;
    let listDom = [];
    searchTypes.map((typeItem, index) => {
      if (searchResult[typeItem].length) {
        showListFlag = true;
        listDom.push(
          <div className="search-result-list" key={index}>
            <div className="search-result-head">{SEARCH_TITLE[typeItem]}:</div>
            <List
              className="result-list-item"
              dataSource={searchResult[typeItem]}
              renderItem={(item, renderIndex) => {
                let listItemIndex = 0;
                for (let i = 0; i < index; i++) {
                  listItemIndex += searchResult[searchTypes[i]].length;
                }
                const indexStr = item.name.toLocaleLowerCase().indexOf(keyWords.toLocaleLowerCase());
                if (~indexStr) {
                  return (
                    <List.Item
                      key={item.key}
                      className={(listItemIndex + renderIndex === selectedSearchItem) ? "selected" : ""}
                      onClick={() => this.handleClickSearchList(typeItem, item)}>
                      {
                        (typeItem === "personalMenu" || typeItem === "adminMenu") && (
                          <span className="menu">
                             {item.bStr.length > 10 ? `...${item.bStr.substr(item.bStr.length - 10)}` : item.bStr}
                            <span className='default-color-font'>{keyWords}</span>
                            {item.aStr.length > 10 ? `${item.aStr.substr(0, 10)}...` : item.aStr}
                            {item.mode && <span className={"f-right"}>{item.mode}</span>}
                           </span>
                        )
                      }
                      {
                        typeItem === "helpDoc" && (
                          <span className="helpDoc">
                              <span className="fstTitle">
                                {
                                  (item.titleBStr && item.titleBStr.length) || (item.titleAStr && item.titleAStr.length) ?
                                    <span>{item.titleBStr}<span className='default-color-font'>{keyWords}</span>{item.titleAStr}</span>
                                    :
                                    item.title
                                }
                              </span>
                              <Divider type="vertical"/>
                              <span>
                                {
                                  (item.contentBStr || item.contentAStr) ?
                                    <span>
                                      {item.contentBStr.length > 10 ? `...${item.contentBStr.substr(item.contentBStr.length - 10)}` : item.contentBStr}
                                      <span className='default-color-font'>{keyWords}</span>
                                      {item.contentAStr.length > 10 ? `${item.contentAStr.substr(0,10)}...` : item.contentAStr}
                                    </span>
                                    :
                                    `${item.content.substr(0,20)}...`
                                }
                              </span>
                            </span>
                        )
                      }
                      {
                        typeItem === "FAQ" && (
                          <p className="FAQ">
                            <a href={`#${item.anchor}`}>
                              <span className="fstTitle">
                                {
                                  (item.titleBStr || item.titleAStr) ?
                                    <span>{item.titleBStr}<span className='default-color-font'>{keyWords}</span>{item.titleAStr}</span>
                                    :
                                    item.title
                                }
                              </span>
                              <span className="sndTitle">
                                <span><b>
                                  {
                                    (item.quesBStr || item.quesAStr) ?
                                      <span>{item.quesBStr}<span className='default-color-font'>{keyWords}</span>{item.quesAStr}</span>
                                      :
                                      item.question
                                  }
                                </b></span>
                                <span>
                                  {
                                    (item.ansBStr || item.ansAStr) ?
                                      <span>
                                        {item.ansBStr.length > 10 ? `...${item.ansBStr.substr(item.ansBStr.length - 10)}` : item.ansBStr}
                                        <span className='default-color-font'>{keyWords}</span>
                                        {item.ansAStr.length > 10 ? `${item.ansAStr.substr(0,10)}...` : item.ansAStr}
                                      </span>
                                      :
                                      `${item.answer.substr(0,20)}...`
                                  }
                                </span>
                              </span>
                            </a>
                          </p>
                        )
                      }
                    </List.Item>
                  )
                } else {//应该不会出现，此处做个容错叭
                  return (
                    <List.Item key={item.key}>
                      {item.name}
                    </List.Item>
                  )
                }
              }}
            />
          </div>
        );
      }
    });
    return (
      <div id="search-result" className="search-result" style={isFocus ? {} : {visibility: "hidden"}}>
        {
          searchLoad ? <p>{messages('dashboard.key139')/*正在搜索...*/}</p> : (showListFlag ? listDom :
            <p>{messages('dashboard.key122')/*无匹配结果*/}</p>)
        }
      </div>
    )
  };

  render() {
    const {searchLoad, isFocus, searchResult, keyWords} = this.state;
    let searchTypes = Object.keys(SEARCH_STANDARD);
    let searchResultLength = 0;
    searchTypes.map((typeItem) => {
      searchResultLength += searchResult[typeItem].length
    });
    const suffix = searchLoad && isFocus ? <Icon type="loading"/> : null;
    return (
      <div className="search-box">
        <Input
          placeholder={messages('dashboard.key127')/*在汇联易平台中搜索*/}
          ref="searchButton"
          prefix={<Icon type="search"/>}
          suffix={suffix}
          onChange={this.handleSearchHuilianyi}
          onKeyDown={this.handleKeyDown}
          onClick={this.handleFocus}
          value={keyWords}
          onBlur={() => {
            setTimeout(() => {
              this.setState({isFocus: false, selectedSearchItem: -1});
              window.addEventListener ? window.addEventListener('keydown', this.handleKeyPress) : window.attachEvent('onkeydown', this.handleKeyPress)
            },200);
          }}
          className={isFocus ? "focus-button" : "search-button"}
        />
        {!!keyWords && this.renderSearchList()}
      </div>
    )
  }
}

GlobalSearch.contextTypes = {
  router: React.PropTypes.object
};

GlobalSearch.propTypes = {
  changeTenantMode: React.PropTypes.func,
  changeAdminMode: React.PropTypes.func,
  isOldCompany: React.PropTypes.bool,
  languageCode:  React.PropTypes.string,
  tenantMode: React.PropTypes.bool,
  adminMode: React.PropTypes.bool
};

function mapStateToProps(state) {
  return {
    authToken: state.main.authToken,
    user: state.login.user,
    userPermissionAllMenus: state.login.userPermissionAllMenus,
    newPermissionSortedMenus: state.login.newPermissionSortedMenus
  }
}

export default connect(mapStateToProps)(GlobalSearch);
